package com.qwt.weather;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 解析气象数据
 *
 * @author 秦先生
 */
public class WeatherParser {

    /**
     * 解析js中变量的json数据
     *
     * @param str     js代码
     * @param varName js变量名称
     */
    public static JSONObject parseVar2Json(String str, String varName) {
        // 正则表达式，只匹配变量名到第一个大括号
        String regex = "var\\s+" + varName + "\\s*=\\s*(\\{)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);

        if (matcher.find()) {
            // 找到变量对应的起始大括号位置
            int startIndex = matcher.end(1) - 1;
            // 使用栈来找到匹配的完整 JSON 对象
            int endIndex = findClosingBrace(str, startIndex);
            if (endIndex != -1) {
                String jsonStr = str.substring(startIndex, endIndex + 1);
                return JSONObject.parseObject(jsonStr);  // 解析 JSON 字符串为 JSONObject
            }
        }
        return new JSONObject();
    }

    /**
     * 将不符合标准的code进行格式化，例如: d1 -> d01
     * @param code 原编码
     * @return 格式化后的编码
     */
    public static String formatCode(String code) {
        if (StrUtil.isBlank(code)) {
            return code;
        }
        // 使用正则表达式匹配以d开头并且后面只有1位数字的情况
        return code.replaceAll("^d(\\d)$", "d0$1");
    }

    /**
     * 寻找从起始位置开始匹配的闭合大括号
     *
     * @param str        原始字符串
     * @param startIndex 起始大括号的位置
     * @return 闭合大括号的位置，如果找不到则返回 -1
     */
    private static int findClosingBrace(String str, int startIndex) {
        int braceCount = 0;
        for (int i = startIndex; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c == '{') {
                braceCount++;
            } else if (c == '}') {
                braceCount--;
                if (braceCount == 0) {
                    // 找到匹配的闭合大括号
                    return i;
                }
            }
        }
        // 未找到匹配的大括号
        return -1;
    }

    /**
     * 解析 dataSK 实时天气信息
     *
     * @param json        dataSK部分的JSON字符串
     * @param weatherInfo WeatherInfo对象，用于存储解析后的结果
     */
    public static void setDataSkIntoWeather(JSONObject json, WeatherInfo weatherInfo) {
        weatherInfo.setCity(json.getString("cityname"))
                .setTemp(json.getString("temp") + "℃")
                .setAqi(json.getString("aqi"))
                .setHumidity(json.getString("sd"))
                .setPressure(json.getString("qy") + "hPa")
                .setCurrentWeather(json.getString("weather"))
                .setCurrentWeatherCode(formatCode(json.getString("weathercode")))
        ;
    }

    /**
     * 解析 cityDZ 实时天气信息
     *
     * @param json        cityDZ部分的JSON字符串
     * @param weatherInfo WeatherInfo对象，用于存储解析后的结果
     */
    public static void setCityDzIntoWeather(JSONObject json, WeatherInfo weatherInfo) {
        JSONObject obj = json.getJSONObject("weatherinfo");
        weatherInfo.setTempMax(obj.getString("temp"))
                .setTempMin(obj.getString("tempn"))
                .setWeather(obj.getString("weather"))
                .setWeatherCode(formatCode(obj.getString("weathercode")))
        ;
    }

    /**
     * 转换 alarmDZ 实时天气信息
     *
     * @param json alarmDZ部分的JSON字符串
     * @return AlarmInfo 用于存储解析后的结果
     */
    public static List<AlarmInfo> getAlarmDzIntoWeather(JSONObject json) {
        JSONArray arr = Optional.ofNullable(json.getJSONArray("w")).orElse(new JSONArray());
        List<AlarmInfo> alarms = new ArrayList<>();

        for (int i = 0; i < arr.size(); i++) {
            JSONObject alarmJson = arr.getJSONObject(i);
            AlarmInfo alarm = new AlarmInfo();
            alarm.setType(alarmJson.getString("w4"));
            alarm.setTypeName(alarmJson.getString("w5"));
            alarm.setLevel(alarmJson.getString("w6"));
            alarm.setLevelName(alarmJson.getString("w7"));
            alarm.setTime(alarmJson.getString("w8"));
            alarm.setTitle(alarmJson.getString("w13"));
            alarm.setDescription(alarmJson.getString("w9"));
            alarm.setCode(alarmJson.getString("w16"));
            alarms.add(alarm);
        }
        return alarms;
    }
}
